<?php
namespace app\install\controller;

use app\BaseController;
use app\common\model\auth\SystemMenu;
use think\facade\View;
use think\facade\Cache;
use think\facade\Request;
use app\admin\service\auth\RoleService;
use app\admin\service\auth\AdminService;
use tmcore\services\ConfigService;

class Index extends BaseController
{
    public function initialize()
    {
        View::config(['layout_on' => false]);
    }

    private function checkInstall() {
        if(file_exists(app()->getRootPath() . '/data/install/install.lock')) {
            die('可能已经安装过本系统了，请删除./data/install目录下面的install.lock文件再尝试');
        };
    }

    /**
     * 主页
     */
    public function index()
    {
        $this->checkInstall();
        $this->assign('url_path', Request::domain());
        return view('/index');
    }

    /**
     * 安装环境检测
     * @return \think\response\Json
     */
    public function envCheck()
    {
        $this->checkInstall();
        $error = true;

        $check_env = check_env();
        $check_dir_file = check_dir_file();
        $check_web_dir_file = check_web_dir_file();

        $check_env_data = [];

        foreach ($check_env as $key => $value) {
            if ($value[3] == 'error') {
                $error = false;
            }

            array_push($check_env_data,[
                'name' => $value[0],
                'require' => $value[1],
                'result' => $value[3],
                'suggest' => $value[2],
            ]);
        }

        $check_dir_file_data = [];

        foreach ($check_dir_file as $key => $value) {
            if ($value[2] == 'error') {
                $error = false;
            }

            array_push($check_dir_file_data,[
                'name' => $value[3],
                'require' => $value[1],
                'result' => $value[2],
                'suggest' => $value[4],
            ]);
        }

        $check_web_dir_file_data = [];

        foreach ($check_web_dir_file as $key => $value) {
            if ($value[2] == 'error') {
                $error = false;
            }

            array_push($check_web_dir_file_data,[
                'name' => $value[3],
                'require' => $value[1],
                'result' => $value[2],
                'suggest' => $value[4],
            ]);
        }

        return json(['code' => 0 ,'data' => [
            'is_submit' => $error,
            'check_env' => $check_env_data,
            'check_dir_file' => $check_dir_file_data,
            'check_web_dir_file' => $check_web_dir_file_data,
        ]]);
    }

    /**
     * 安装信息
     * @return \think\response\Json
     */
    public function installInfo() {
        $info = install_cache('get');
        if ($info && array_key_exists('sysSuccess', $info)) install_cache('delete');
        $data  = [];
        if($info) {
            foreach ($info as $val) {
                array_push($data, $val);
            }
        }
        return json(['code' => 0, 'data' => $data?:[]]);
    }

    /**
     * 系统安装
     * @return \think\response\Json
     */
    public function submit()
    {
        $this->checkInstall();

        // 检测信息
        $data = input('post.');

        if (!$data['db']['hostname']) {
            return json(['code'=> -1, 'msg' => '请填写数据库地址!']);
        }
        if (!$data['db']['hostport']) {
            return json(['code'=> -1, 'msg' => '请填写数据库端口!']);
        }
        if (!$data['db']['database']) {
            return json(['code'=> -1, 'msg' => '请填写数据库名称!']);
        }
        if (!$data['db']['username']) {
            return json(['code'=> -1, 'msg' => '请填写数据库用户名!']);
        }
        if (!$data['db']['password']) {
            return json(['code'=> -1, 'msg' => '请填写数据库密码!']);
        }
        if (!$data['db']['prefix']) {
            return json(['code'=> -1, 'msg' => '请填写数据表前缀!']);
        }
        if (!$data['username']) {
            return json(['code'=> -1, 'msg' => '请填写用户名!']);
        }
        if (!$data['password']) {
            return json(['code'=> -1, 'msg' => '请填写密码!']);
        }
        if (!$data['password2']) {
            return json(['code'=> -1, 'msg' => '请填写重复密码!']);
        }
        if ($data['password'] != $data['password2']) {
            return json(['code'=> -1, 'msg' => '重复密码不匹配!']);
        }

        // 防止不存在的数据库导致连接数据库失败
        $db_name = $data['db']['database'];
        $data['db']['basename'] = $db_name;
        unset($data['db']['database']);

        // 延长执行时间
        set_time_limit(300);

        try{
            Cache::set('sys_install_info', null);
            // 创建数据库连接
            $db_instance = @mysqli_connect($data['db']['hostname'], $data['db']['username'], $data['db']['password'], NULL, $data['db']['hostport']);
            if(mysqli_connect_errno()) {
                throw new \Exception('数据库连接失败，请检查连接信息是否正确！');
            }
            //确定数据库中是否存在数据表
            $result = mysqli_query($db_instance, 'select count(table_name) as table_count from information_schema.`TABLES` where table_schema="'.$db_name.'"');
            $result = $result->fetch_array();
            if ($result["table_count"] > 0) {
                throw new \Exception('该数据库已存在数据表，请先清空数据!');
            }

            //设置字符编码
            mysqli_set_charset($db_instance, "utf8");
            $version = mysqli_get_server_info($db_instance);
            if ($version < 5.1) {
                throw new \Exception('数据库版本太低! 必须5.1以上版本!');
            }

            if(!mysqli_select_db($db_instance, $db_name)) {
                // 创建数据库
                $sql = "CREATE DATABASE IF NOT EXISTS `{$db_name}` DEFAULT CHARACTER SET utf8";
                try {
                    mysqli_query($db_instance, $sql);
                } catch (\Exception $e) {
                    throw new \Exception($e->getMessage());
                }
            }

            $web_dirs = ['admin', 'uniapp', 'pc'];

            // 修改前端配置文件
            foreach ($web_dirs as $web_dir) {
                write_web_config($web_dir);
            }

            // 修改数据库配置文件
            $res = write_config($data['db']);
            if($res) {
                install_cache('set', 'envConfig', '配置文件写入成功!');
            } else {
                throw new \Exception('配置文件写入失败!');
            }

            // 开始安装
            $file = app()->getRootPath() .'app/install/data/tm_admin.sql';
            $sqlData = get_mysql_data($file, 'tm_', $data['db']['prefix']);

            install_cache('set', 'sqlInstall', '数据库安装中，请等待...!');

            //循环执行sql
            foreach ($sqlData as $sql) {
                $res = mysqli_query($db_instance, $sql);
                if(!$res) throw new \Exception(mysqli_error($db_instance));
            }

            install_cache('set', 'sqlSuccess', '数据库安装完成!');

            // 添加角色
            $res = RoleService::add([
                'name' => '超级管理员',
                'menu_id' => SystemMenu::column('id')
            ]);

            if(!$res) {
                throw new \Exception('添加管理员角色失败!');
            }

            // 添加管理员
            $res = AdminService::add([
                'account' => $data['username'],
                'name' =>  $data['username'],
                'password' => $data['password'],
                'role_id' => [1],
                'disable' => 0,
                'dept_id' => 0,
                'jobs_id' => 0,
                'multipoint_login' => 1,
                'mobile' => '',
                'email' => '',
            ], true);

            if(!$res) {
                throw new \Exception('创建管理员失败!');
            }

            install_cache('set', 'adminSuccess', '创建管理员成功!');

        } catch (\Exception $e) {
            return json(['code'=> -1, 'msg' => $e->getMessage()]);
        }

        // 系统缓存生成
        (new ConfigService)->setConfig('create', 'all');

        // 创建文件锁
        $res = file_put_contents( app()->getRootPath() . '/data/install/install.lock', 'success');
        if(!$res) return json(['code'=> -1, 'msg' => '创建检验文件install.lock失败!']);

        install_cache('set', 'sysSuccess', '系统安装成功!');

        // 恢复页面执行时间
        set_time_limit(30);

        return json(['code'=> 0, 'msg' => 'success', 'data' => [
            'url' => Request::domain() . '/admin/',
            'msg' => '如需重新安装，请清空数据表并删除./data/install目录下install.lock文件'
        ]]);
    }
}
